<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>



        // 回调函数：将一个函数以参数的形式传入到另一个函数中并且被调用执行
        // 目的就是不关注要执行谁，执行就行了
        // function fn1(fn){
        //     fn();
        // }   
        
        // function fn2(){
        //     console.log("aaa");
        // }
        // function fn3(){
        //     console.log("bbb");
        // }

        // fn1(fn2);
        // fn1(fn3);

// 执行过程：执行第一个fn的时候是，将fn2等同于fn，之后执行fn就是执行fn2
// 执行第二个fn的时候时候，fn3等同于fn，之后执行时fn就是执行fn3





// 通过插入不同的函数，解决不同的问题
        // function fn1(a,b,fn){
        //     return fn(a,b);
        // }

        // function fn2(a,b){
        //     return a+b;
        // }
        // function fn3(a,b){
        //     return a-b;
        // }
        // function fn4(a,b){
        //     return a*b;
        // }
        // function fn5(a,b){
        //     return a/b;
        // }
        
        // var s=fn1(3,5,fn5);
        // console.log(s);

// 要求不高，背会


// 桥接模式：
    // function fn1(){
    //     var fn=arguments[arguments.length-1];
    //     var s=arguments[0];
    //     for(var i=1;i<arguments.length-1;i++){
    //        s=fn(s,arguments[i]);
    //     }
    //     return s;
    // }

    // var p=fn1(1,2,3,4,5,6,function(s,n){
    //     return s*n;
    // })
    // console.log(p);

// 执行过程：执行fn1函数时，定义fn函数等于fn1中的function，在fn中传递进来
// 两个参数，循环第一次时，其中s是fn的的第一项，arguments[1]是fn的第二项
// 而fn等同于function，所以两者的参数相对应相等，再通过return返回计算后的值
// 给fn也就是s，完成循环后再通过return返回给fn1 ，也就是p的值




        // setInterval(function(){

        // },16)

        // 每16毫秒访问一次函数，并添加一个标识，就是setInterval的id，起名不能起id=什么
        // 因为id是Windows属性


        //      var i=0;
        //    var ids=setInterval(function(){
        //         i++;
        //         console.log(i);
        //         if(i>3)  clearInterval(ids);
        //     },16);

// 每16毫秒进入函数一次，输出i的值，当i大于3时，就会将之后的清掉
// 输出结果为 1 2 3 4 



        //     var i=0;
        //    var ids=setInterval(function(a,b,c){
        //         i++;
        //         console.log(a,b,c);
        //         if(i>3)  clearInterval(ids);
        //     },16,1,2,3);

            // 1 2 3是向回调函数（function）中传参，等同于a b c 对应的值

            // 结构 ids=setInterval(回调函数,间隔时间,参数1,参数2...)
            // ids就是这个时间间隔 标识id，可以通过clearInterval(ids)解除当前时间间隔设定
            // 回调函数会被在间隔时间达到时调用，参数1，参数2就是向回调函数传参的方式


        //     var ids;
        // for(var i=0;i<10;i++){

        //     ids=setInterval(function(){
        //         console.log(n);
        //     })
        // }

        // 瞬间执行完的循环时同步的，而延迟执行的是异步的，在异步执行时，同步时的变量可能早就变化了
// 当setInterval在循环中时，由于循环间隔是瞬间，而setInterval最少也要1毫秒，所以有种现象是
// 当for开始循环时，setInterval开始执行第一次，里面的函数还没有执行的时候，for开始了第二次循环
// 最后创建了10个时间间隔，就无法进入执行函数



        
        // var ids;
        // for(var i=0;i<10;i++){
        //     console.log(ids);
        //     ids=setInterval(function(){
            
        //     })
        // }
// 输出结果是有变化的，undefined 1-9




        // var ids;
        // for(var i=0;i<10;i++){

        //     ids=setInterval(function(a,n){
        //         console.log(n);
        //     },3000,ids,i)
        // }

// 瞬间执行完的循环时同步的，而延迟执行的是异步的，在异步执行时，同步时的变量可能早就变化了
// 时间间隔为3秒，回调函数为setInterval，回调参数是i，
// 利用传参的形式，将i传递给n输出即可，把ids当时的变量传过去



// 用setTimeOut重构setInterval
        // function setInterval_1(fn,time){
        //    setTimeout(function(n){
        //         fn(n);
        //         setInterval_1(fn,time,n);
        //     },time,arguments[2]);

        // }

        // setInterval_1(function(n){
        //     console.log(n);
        // },1000,5)

// 执行过程：调用setInterval 函数时，将fn等同于function 执行fn的时候就输出了一次n，
// time等于1000毫秒传入调用setInterval时，执行中间的setInterval，再次调用fn，等效
// 于再次把下面这个setIterval，输出一次n




        // function fn1(color,time){
        //     setTimeout(function(){
        //         console.log(color);
        //         if(color==="红"){
        //             fn1("黄",time);
        //         }else if(color==="黄"){
        //             fn1("绿",time);
        //         }else if(color==="绿"){
        //             fn1("红",time);
        //         }
        //     },time)
        // }

        // fn1("红",1000);

// 执行fn1时，将红带入，时间1000毫秒带入，setTimeout每1000毫秒输出一次颜色
// 最开始的状态是红色带入，进行循环，每次调用都是fn1 调用function



// 异步回调使用
        // function redColor(fn1,fn2){
        //   var ids=setTimeout(function(){
        //         console.log("红色")
        //         clearTimeout(ids);
        //         fn1(fn2,redColor);
        //     },2000);
        // }

        // function yellowColor(fn1,fn2){
        //     var ids=setTimeout(function(){
        //         console.log("黄色")
        //         clearTimeout(ids);
        //         fn1(fn2,yellowColor);
        //     },2000);
        // }

        // function greenColor(fn1,fn2){
        //     var ids=setTimeout(function(){
        //         console.log("绿色")
        //         clearTimeout(ids);
        //         fn1(fn2,greenColor);
        //     },2000);
        // }

        // redColor(yellowColor,greenColor);

// 执行过程：函数最开始执行redcolor，传入参数，fn1等同于yellowcolor ，fn2等同于greencolor
// 进入下一个函数，间隔2000毫秒，输出红色，之后再用fn1调用下面的黄色，fn2等同于 绿色，
// 黄色输出后，此时的fn1 执行的是绿色，输出绿色后，再次调用fn1 此时的fn1是红色，达到效果






 // ------------------回调循环


        // function fn1(fn,n){
        //     if(n===undefined) n=0;
        //     n++;
        //     return fn(fn1,n);
        // }

        // function fn2(fn,n){
        //     n++;
        //     if(n===10) return n;
        //     return fn(fn2,n);
        // }

        // var s=fn1(fn2);
        // console.log(s);//10


        // 执行过程：要输出对s的求和，就需要执行fn1(fn2)，调用fn1的函数，此时fn等同于fn2
        // 再执行fn的时候，就是执行fn2，此时的fn就等同于fn1 当再次执行fn时 ，就是执行fn1
        // 此时就造成了一个循环，n在每次循环时数值发生改变，当n等于10时，需要给返回值
        // return n就是将fn2值返回给fn(fn1，n)，就是fn1，等同于fn(fn2,n)，再将值返回即可













    </script>
</body>
</html>